package com.rent.web.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator;
import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.client.RestTemplate;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * @Author zhang
 * @create 2022/9/13 13:56
 */
@Configuration
public class BeanConfig {

    //创建一个ipKeyResolver 指定用户的IP
    @Bean(name = "ipKeyResolver")
    public KeyResolver keyResolver() {
        return exchange -> {
            //1.获取请求request对象
            ServerHttpRequest request = exchange.getRequest();
            //2.从request中获取ip地址
            String hostString = Objects.requireNonNull(request.getRemoteAddress()).getHostString();//Ip地址
            //3.返回
            return Mono.just(hostString);
        };
    }

    /**
     * -@LoadBalanced注解修饰的RestTemplate才能实现服务名的调用，没有修饰的RestTemplate是没有该功能的，只能使用IP、Port访问微服务。
     */
    // http请求调用Bean
    @Bean(name = "restTemplate")
    @LoadBalanced
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setReadTimeout(60 * 1000);
        requestFactory.setConnectTimeout(60 * 1000);
        return new RestTemplate(requestFactory);
    }

    // 网关路由配置bean
    @Bean
    public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(ReactiveDiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
        return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
    }

    @Autowired
    private LoadBalancerClientFactory loadBalancerClientFactory;

    @Bean
    public LoadBalancerClient blockingLoadBalancerClient() {
        return new CustomBlockingLoadBalancerClient(loadBalancerClientFactory);
    }

}
